package service

import (
	"delivery-server/utils/response"
	"github.com/go-xorm/xorm"
)

// PlaceService 地点服务
type PlaceService interface {

	// 查询一个地点是否存在
	queryPlace(name string) (exist bool, err error)

	// 新增地点
	addPlace(name string) (success bool, err error)

	// AllPlaces 获取所有地点
	AllPlaces() (results []map[string]string, err error)

	// DeletePlace 删除某个地点
	DeletePlace(placeId int) (success bool, err error)

	// TryToAddPlace 新增地点事务
	TryToAddPlace(name string) (code int)
}

// NewPlaceService 创建一个新的管理员服务对象
func NewPlaceService(engine *xorm.Engine) PlaceService {
	return &placeService{
		Engine: engine,
	}
}

// 地点服务结构体
type placeService struct {
	Engine *xorm.Engine
}

// 查询一个地点是否存在
func (ps placeService) queryPlace(name string) (exist bool, err error) {

	sqlStr := "SELECT id FROM place WHERE name = ? AND invalidity = 0"
	results, err := ps.Engine.QueryString(sqlStr, name)
	exist = len(results) > 0
	return
}

// 新增一个地点
func (ps placeService) addPlace(name string) (success bool, err error) {

	// 向place中新增一个名字
	sqlStr := "INSERT INTO place(name) VALUES (?)"
	_, err = ps.Engine.Exec(sqlStr, name)
	success = err == nil
	return
}

// TryToAddPlace 新增地点事务
func (ps placeService) TryToAddPlace(name string) (code int) {

	// 创建session对象
	session := ps.Engine.NewSession()
	defer session.Close()

	// 事务开始
	err := session.Begin()
	if err != nil {
		code = response.ServerErrCode
		return
	}

	// 查询地点名是否已被占用
	exist, err := ps.queryPlace(name)
	if err != nil {
		code = response.ServerErrCode
		return
	}
	if exist {
		err = session.Rollback()
		if err == nil {
			code = response.PlaceExistCode
		} else {
			code = response.ServerErrCode
		}
		return
	}

	// 插入地点数据
	success, err := ps.addPlace(name)
	if err != nil || !success {
		err = session.Rollback()
		if err != nil {
			code = response.ServerErrCode
			return
		}
	}

	// 提交事务
	err = session.Commit()
	if err != nil {
		code = response.ServerErrCode
		return
	}

	// 请求成功
	code = response.SuccessCode
	return
}

// AllPlaces 获取所有的地点数据
func (ps placeService) AllPlaces() (results []map[string]string, err error) {

	// 获取所有的有效地点数据
	sqlStr := "SELECT id, name FROM place WHERE invalidity = 0"
	results, err = ps.Engine.QueryString(sqlStr)
	return
}

// DeletePlace 删除指定地点
func (ps placeService) DeletePlace(placeId int) (success bool, err error) {

	// 将指定id的地点设为无效
	sqlStr := "UPDATE place SET invalidity = 1 WHERE id = ?"
	_, err = ps.Engine.Exec(sqlStr, placeId)
	success = err == nil
	return
}